#ifndef __ZHONG_CHAT_SESSION__
#define __ZHONG_CHAT_SESSION__
#include "Factory.hpp"
#include "chat_session.hxx"
#include "chat_session-odb.hxx"
#include "chat_session_member.hxx"
#include "chat_session_member-odb.hxx"
namespace bite_im
{
    class ChatSessionTable
    {
    public:
        using ptr = std::shared_ptr<ChatSessionTable>;
        ChatSessionTable() {}
        ChatSessionTable(const DBPtr &db) : _db(db) {}

        // 新增申请事件
        bool insert(ChatSession &cs)
        {
            // 申请事件一般来说是单方面的
            try
            {
                // 获取事务对象，开启事务
                odb::transaction transaction(_db->begin());

                _db->persist(cs);
                // 提交事务
                transaction.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("添加会话[{}]信息失败，原因[{}]", cs.chat_session_id(), e.what());
                return false;
            }
            return true;
        }

        // 删除会话信息
        bool remove(const std::string &session_id)
        {
            try
            {
                // 获取事务对象，开启事务
                odb::transaction transaction(_db->begin());
                using query = odb::query<ChatSession>;
                _db->erase_query<ChatSession>(query::chat_session_id == session_id);

                using mquery = odb::query<ChatSessionMember>;        
                _db->erase_query<ChatSessionMember>(mquery::session_id == session_id);
                // 提交事务
                transaction.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("删除会话[{}]信息失败，原因[{}]", session_id, e.what());
                return false;
            }
            return true;
        }
        // 通过用户id和好友id
        bool remove(const std::string &user_id, const std::string &peer_id)
        {
            try
            {
                // 获取事务对象，开启事务
                odb::transaction transaction(_db->begin());
                // 通过user_id和peer_id获得session_id
                using query_find = odb::query<SingleChatSession>;
                // 查询当前的user_id是作为谁的好友申请关系的peer_id，同时确定user和peer，那么也只能获得一个对象
                auto res = _db->query_one<bite_im::SingleChatSession>(query_find::css::chat_session_type == bite_im::ChatSessionType::SINGLE &&
                                                                      query_find::csm1::user_id == user_id &&
                                                                      query_find::csm2::user_id == peer_id);

                std::string session_id = res->chat_session_id;
                // 进行删除
                using query = odb::query<ChatSession>;
                _db->erase_query<ChatSession>(query::chat_session_id == session_id);

                using mquery = odb::query<ChatSessionMember>;
                // 需要顺带删除chat_session_member中的对应会话信息
                _db->erase_query<ChatSessionMember>(mquery::session_id == session_id);
                // 提交事务
                transaction.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("删除会话信息失败，原因[{}]", e.what());
                return false;
            }
            return true;
        }

        // 获取指定的会话信息
        std::shared_ptr<ChatSession> select(const std::string &session_id)
        {
            std::shared_ptr<ChatSession> cs;
            try
            {
                // 3.获取事务对象，开启事务
                odb::transaction transaction(_db->begin());
                using query = odb::query<ChatSession>;
                cs.reset(_db->query_one<ChatSession>(query::chat_session_id == session_id));

                // 4.提交事务
                transaction.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("获取会话[{}]信息失败，原因[{}]", session_id, e.what());
            }
            return cs;
        }

        // 获取当前用户的所有单聊会话信息
        std::vector<SingleChatSession> singleChatSession(const std::string &user_id)
        {
            std::vector<SingleChatSession> single_list;
            try
            {
                // 3.获取事务对象，开启事务
                odb::transaction transaction(_db->begin());
                using query = odb::query<SingleChatSession>;
                using result = odb::result<SingleChatSession>;
                // 查询当前的user_id是作为谁的好友申请关系的peer_id
                result ret(_db->query<SingleChatSession>(query::css::chat_session_type == bite_im::ChatSessionType::SINGLE &&
                                                         query::csm1::user_id == user_id &&
                                                         query::csm2::user_id != query::csm1::user_id));
                for (auto it = ret.begin(); it != ret.end(); ++it)
                {
                    single_list.push_back(*it);
                }
                // 4.提交事务
                transaction.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("获取用户[{}]的所有单聊信息失败，原因[{}]", user_id, e.what());
            }
            return single_list;
        }
        // 获取当前用户的所有群聊会话信息
        std::vector<GroupChatSession> groupChatSession(const std::string &user_id)
        {
            std::vector<GroupChatSession> group_list;
            try
            {
                // 3.获取事务对象，开启事务
                odb::transaction transaction(_db->begin());
                using query = odb::query<GroupChatSession>;
                using result = odb::result<GroupChatSession>;
                // 通过过滤条件查询满足的ret列表
                result ret(_db->query<GroupChatSession>(query::css::chat_session_type == bite_im::ChatSessionType::GROUP &&
                                                        query::csm1::user_id == user_id));
                for (auto it = ret.begin(); it != ret.end(); ++it)
                {
                    group_list.push_back(*it);
                }
                // 4.提交事务
                transaction.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("获取用户[{}]的所有群聊信息失败，原因[{}]", user_id, e.what());
            }
            return group_list;
        }

    private:
        DBPtr _db;
    };

}
#endif